const AbstractMockApi = require('./AbstractMockApi')

class MockDocstoreApi extends AbstractMockApi {
  reset() {
    this.docs = {}
  }

  applyRoutes() {
    this.app.post('/project/:projectId/doc/:docId', (req, res) => {
      const { projectId, docId } = req.params
      const { lines, version, ranges } = req.body
      if (this.docs[projectId] == null) {
        this.docs[projectId] = {}
      }
      if (this.docs[projectId][docId] == null) {
        this.docs[projectId][docId] = {}
      }
      const { version: oldVersion, deleted } = this.docs[projectId][docId]
      this.docs[projectId][docId] = { lines, version, ranges, deleted }
      if (this.docs[projectId][docId].rev == null) {
        this.docs[projectId][docId].rev = 0
      }
      this.docs[projectId][docId].rev += 1
      this.docs[projectId][docId]._id = docId
      res.json({
        modified: oldVersion !== version,
        rev: this.docs[projectId][docId].rev
      })
    })

    this.app.get('/project/:projectId/doc', (req, res) => {
      res.json(Object.values(this.docs[req.params.projectId] || {}))
    })

    this.app.get('/project/:projectId/doc/:docId', (req, res) => {
      const { projectId, docId } = req.params
      const doc = this.docs[projectId][docId]
      if (!doc || (doc.deleted && !req.query.include_deleted)) {
        res.sendStatus(404)
      } else {
        res.json(doc)
      }
    })

    this.app.get('/project/:projectId/doc/:docId/deleted', (req, res) => {
      const { projectId, docId } = req.params
      if (!this.docs[projectId] || !this.docs[projectId][docId]) {
        res.sendStatus(404)
      } else {
        res.json({ deleted: Boolean(this.docs[projectId][docId].deleted) })
      }
    })

    this.app.delete('/project/:projectId/doc/:docId', (req, res) => {
      const { projectId, docId } = req.params
      if (!this.docs[projectId]) {
        res.sendStatus(404)
      } else if (!this.docs[projectId][docId]) {
        res.sendStatus(404)
      } else {
        this.docs[projectId][docId].deleted = true
        res.sendStatus(204)
      }
    })

    this.app.post('/project/:projectId/destroy', (req, res) => {
      const { projectId } = req.params
      delete this.docs[projectId]
      res.sendStatus(204)
    })
  }
}

module.exports = MockDocstoreApi

// type hint for the inherited `instance` method
/**
 * @function instance
 * @memberOf MockDocstoreApi
 * @static
 * @returns {MockDocstoreApi}
 */
